package com.unitd.modules.gen.entity;

import com.google.common.collect.Lists;
import com.unitd.comm.entity.SysEntity;
import com.unitd.frame.comm.utils.StringUtils;
import org.hibernate.validator.constraints.Length;

import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.List;

/**
 * @desc 生成代码的业务表字段Entity, 用于定义该表结构的列对象信息
 * @filename GenTableColumn.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0 
 * @date 2017-04-29
 */ 
@Table(name = "gen_table_column")
public class GenTableColumn extends SysEntity {

	/** 归属表编号 */
	@Column(name = "gen_table_id")
	private String genTableId;
	/** 名称 */
	@Column(name = "column_name")
	private String columnName;
	/** 描述 */
	private String comments;
	/** 列的数据类型 */
	@Column(name = "jdbc_type")
	private String jdbcType;
	/** JAVA类型(包括基本的java数据类型和自定义的) */
	@Column(name = "java_type")
	private String javaType;
	/** 列对应的Java属性名称 */
	@Column(name = "java_field")
	private String javaField;
	/** 列对应的基本JAVA类型 */
	@Column(name = "base_java_type")
	private String baseJavaType;
	/** 列对应的基本Java字段名 */
	@Column(name = "base_java_field")
	private String baseJavaField;
	/** 是否主键（1主键; 0:非主键） */
	@Column(name = "is_pk")
	private String isPk;
	/** 是否可为空（1:可为空;0:不为空） */
	@Column(name = "is_null")
	private String isNull;
	/** 是否为插入字段（1:插入字段; 0:非插入字段） */
	@Column(name = "is_insert")
	private String isInsert;
	/** 是否编辑字段（1:编辑字段） */
	@Column(name = "is_edit")
	private String isEdit;
	/** 是否列表字段（1:列表字段） */
	@Column(name = "is_list")
	private String isList;
	/** 是否查询字段（1:查询字段） */
	@Column(name = "is_query")
	private String isQuery;
	/** 查询方式（等于、不等于、大于、小于、范围、左LIKE、右LIKE、左右LIKE） */
	@Column(name = "query_type")
	private String queryType;
	/** 字段生成方案（文本框、文本域、下拉框、复选框、单选框、字典选择、人员选择、部门选择、区域选择） */
	@Column(name = "show_type")
	private String showType;

	/** 字典类型 */
	@Column(name = "dict_type")
	private String dictType;
	/** 其它设置（扩展字段JSON） */
	private String settings;
	/** 排序（升序） */
	private Long sort;

	/** 归属表 */
	@Transient
	private GenTable genTable;

	/**
	 * @desc 构造方法 GenTableColumn
	 */
	public GenTableColumn(String id, String genTableId, String columnName, String comments, String jdbcType, String javaType, String javaField, String baseJavaType, String baseJavaField, String isPk, String isNull, String isInsert, String isEdit, String isList, String isQuery, String queryType, String showType, String dictType, String settings, Long sort, String createBy, java.util.Date createDate, String updateBy, java.util.Date updateDate, String remarks, String delFlag) {
		this.id = id;
		this.genTableId = genTableId;
		this.columnName = columnName;
		this.comments = comments;
		this.jdbcType = jdbcType;
		this.javaType = javaType;
		this.javaField = javaField;
		this.baseJavaType = baseJavaType;
		this.baseJavaField = baseJavaField;
		this.isPk = isPk;
		this.isNull = isNull;
		this.isInsert = isInsert;
		this.isEdit = isEdit;
		this.isList = isList;
		this.isQuery = isQuery;
		this.queryType = queryType;
		this.showType = showType;
		this.dictType = dictType;
		this.settings = settings;
		this.sort = sort;
		this.createBy = createBy;
		this.createDate = createDate;
		this.updateBy = updateBy;
		this.updateDate = updateDate;
		this.remarks = remarks;
		this.delFlag = delFlag;
	}

	public GenTableColumn(GenTable genTable) {
		this.genTable = genTable;
	}

	/**
	 * @desc 构造方法 GenTableColumn
	 */
	public GenTableColumn() {
		super();
	}

	/**
	 * @desc 获取归属表编号
	 * @return gen_table_id - 归属表编号
	 */
	public String getGenTableId() {
		return genTableId;
	}

	/**
	 * @desc 设置归属表编号
	 * @param genTableId 归属表编号
	 */
	public void setGenTableId(String genTableId) {
		this.genTableId = genTableId;
	}

	/**
	 * @desc 获取名称
	 * @return column_name - 名称
	 */
	@Length(min = 1, max = 200)
	public String getColumnName() {
		return columnName;
	}

	/**
	 * @desc 设置名称
	 * @param columnName 名称
	 */
	public void setColumnName(String columnName) {
		this.columnName = columnName == null ? null : columnName.trim();
	}

	/**
	 * @desc 获取描述
	 * @return comments - 描述
	 */
	public String getComments() {
		return comments;
	}

	/**
	 * @desc 设置描述
	 * @param comments 描述
	 */
	public void setComments(String comments) {
		this.comments = comments == null ? null : comments.trim();
	}

	/**
	 * @desc 获取列的数据类型
	 * @return jdbc_type - 列的数据类型
	 */
	public String getJdbcType() {
		return jdbcType;
	}

	/**
	 * @desc 设置列的数据类型
	 * @param jdbcType 列的数据类型
	 */
	public void setJdbcType(String jdbcType) {
		this.jdbcType = jdbcType == null ? null : jdbcType.trim();
	}

	/**
	 * @desc 获取JAVA类型
	 * @return java_type - JAVA类型
	 */
	public String getJavaType() {
		return javaType;
	}

	/**
	 * @desc 设置JAVA类型
	 * @param javaType JAVA类型
	 */
	public void setJavaType(String javaType) {
		this.javaType = javaType == null ? null : javaType.trim();
	}

	/**
	 * @desc 获取JAVA字段名
	 * @return java_field - JAVA字段名
	 */
	public String getJavaField() {
		return javaField;
	}

	/**
	 * @desc 设置JAVA字段名
	 * @param javaField JAVA字段名
	 */
	public void setJavaField(String javaField) {
		this.javaField = javaField == null ? null : javaField.trim();
	}

	/**
	 * @desc 获取列对应的基本JAVA类型
	 * @return base_java_type - 列对应的基本JAVA类型
	 */
	public String getBaseJavaType() {
		return baseJavaType;
	}

	/**
	 * @desc 设置列对应的基本JAVA类型
	 * @param baseJavaType 列对应的基本JAVA类型
	 */
	public void setBaseJavaType(String baseJavaType) {
		this.baseJavaType = baseJavaType == null ? null : baseJavaType.trim();
	}

	/**
	 * @desc 获取列对应的基本Java字段名
	 * @return base_java_field - 列对应的基本Java字段名
	 */
	public String getBaseJavaField() {
		return baseJavaField;
	}

	/**
	 * @desc 设置列对应的基本Java字段名
	 * @param baseJavaField 列对应的基本Java字段名
	 */
	public void setBaseJavaField(String baseJavaField) {
		this.baseJavaField = baseJavaField == null ? null : baseJavaField.trim();
	}

	/**
	 * @desc 获取是否主键（1主键; 0:非主键）
	 * @return is_pk - 是否主键（1主键; 0:非主键）
	 */
	public String getIsPk() {
		return isPk;
	}

	/**
	 * @desc 设置是否主键（1主键; 0:非主键）
	 * @param isPk 是否主键（1主键; 0:非主键）
	 */
	public void setIsPk(String isPk) {
		this.isPk = isPk == null ? null : isPk.trim();
	}

	/**
	 * @desc 获取是否可为空（1:可为空;0:不为空）
	 * @return is_null - 是否可为空（1:可为空;0:不为空）
	 */
	public String getIsNull() {
		return isNull;
	}

	/**
	 * @desc 设置是否可为空（1:可为空;0:不为空）
	 * @param isNull 是否可为空（1:可为空;0:不为空）
	 */
	public void setIsNull(String isNull) {
		this.isNull = isNull == null ? null : isNull.trim();
	}

	/**
	 * @desc 获取是否为插入字段（1:插入字段; 0:非插入字段）
	 * @return is_insert - 是否为插入字段（1:插入字段; 0:非插入字段）
	 */
	public String getIsInsert() {
		return isInsert;
	}

	/**
	 * @desc 设置是否为插入字段（1:插入字段; 0:非插入字段）
	 * @param isInsert 是否为插入字段（1:插入字段; 0:非插入字段）
	 */
	public void setIsInsert(String isInsert) {
		this.isInsert = isInsert == null ? null : isInsert.trim();
	}

	/**
	 * @desc 获取是否编辑字段（1:编辑字段）
	 * @return is_edit - 是否编辑字段（1:编辑字段）
	 */
	public String getIsEdit() {
		return isEdit;
	}

	/**
	 * @desc 设置是否编辑字段（1:编辑字段）
	 * @param isEdit 是否编辑字段（1:编辑字段）
	 */
	public void setIsEdit(String isEdit) {
		this.isEdit = isEdit == null ? null : isEdit.trim();
	}

	/**
	 * @desc 获取是否列表字段（1:列表字段）
	 * @return is_list - 是否列表字段（1:列表字段）
	 */
	public String getIsList() {
		return isList;
	}

	/**
	 * @desc 设置是否列表字段（1:列表字段）
	 * @param isList 是否列表字段（1:列表字段）
	 */
	public void setIsList(String isList) {
		this.isList = isList == null ? null : isList.trim();
	}

	/**
	 * @desc 获取是否查询字段（1:查询字段）
	 * @return is_query - 是否查询字段（1:查询字段）
	 */
	public String getIsQuery() {
		return isQuery;
	}

	/**
	 * @desc 设置是否查询字段（1:查询字段）
	 * @param isQuery 是否查询字段（1:查询字段）
	 */
	public void setIsQuery(String isQuery) {
		this.isQuery = isQuery == null ? null : isQuery.trim();
	}

	/**
	 * @desc 获取查询方式（等于、不等于、大于、小于、范围、左LIKE、右LIKE、左右LIKE）
	 * @return query_type - 查询方式（等于、不等于、大于、小于、范围、左LIKE、右LIKE、左右LIKE）
	 */
	public String getQueryType() {
		return queryType;
	}

	/**
	 * @desc 设置查询方式（等于、不等于、大于、小于、范围、左LIKE、右LIKE、左右LIKE）
	 * @param queryType 查询方式（等于、不等于、大于、小于、范围、左LIKE、右LIKE、左右LIKE）
	 */
	public void setQueryType(String queryType) {
		this.queryType = queryType == null ? null : queryType.trim();
	}

	/**
	 * @desc 获取字段生成方案（文本框、文本域、下拉框、复选框、单选框、字典选择、人员选择、部门选择、区域选择）
	 * @return show_type - 字段生成方案（文本框、文本域、下拉框、复选框、单选框、字典选择、人员选择、部门选择、区域选择）
	 */
	public String getShowType() {
		return showType;
	}

	/**
	 * @desc 设置字段生成方案（文本框、文本域、下拉框、复选框、单选框、字典选择、人员选择、部门选择、区域选择）
	 * @param showType 字段生成方案（文本框、文本域、下拉框、复选框、单选框、字典选择、人员选择、部门选择、区域选择）
	 */
	public void setShowType(String showType) {
		this.showType = showType == null ? null : showType.trim();
	}

	/**
	 * @desc 获取字典类型
	 * @return dict_type - 字典类型
	 */
	public String getDictType() {
		return dictType == null ? "" : dictType;
	}

	/**
	 * @desc 设置字典类型
	 * @param dictType 字典类型
	 */
	public void setDictType(String dictType) {
		this.dictType = dictType == null ? null : dictType.trim();
	}

	/**
	 * @desc 获取其它设置（扩展字段JSON）
	 * @return settings - 其它设置（扩展字段JSON）
	 */
	public String getSettings() {
		return settings;
	}

	/**
	 * @desc 设置其它设置（扩展字段JSON）
	 * @param settings 其它设置（扩展字段JSON）
	 */
	public void setSettings(String settings) {
		this.settings = settings == null ? null : settings.trim();
	}

	/**
	 * @desc 获取排序（升序）
	 * @return sort - 排序（升序）
	 */
	public Long getSort() {
		return sort;
	}

	/**
	 * @desc 设置排序（升序）
	 * @param sort 排序（升序）
	 */
	public void setSort(Long sort) {
		this.sort = sort;
	}

	public GenTable getGenTable() {
		return genTable;
	}

	public void setGenTable(GenTable genTable) {
		this.genTable = genTable;
	}

	/**
	 * @desc 获取列名和说明
	 * @return 列名和说明
	 */
	public String getNameAndComments() {
		return getColumnName() + (comments == null ? "" : "  :  " + comments);
	}

	/**
	 * @desc 获取字符串长度
	 * @return 字符串长度
	 */
	public String getDataLength() {
		String[] ss = StringUtils.split(StringUtils.substringBetween(getJdbcType(), "(", ")"), ",");
		if (ss != null && ss.length == 1) {// && "String".equals(getJavaType())){
			return ss[0];
		}
		return "0";
	}

	/**
	 * @desc 获取数字类型BigDecimal的整数位和小数位的长度
	 * @return BigDecimal的整数位
	 */
	public String[] getNumLength() {
		return StringUtils.split(StringUtils.substringBetween(getJdbcType(), "(", ")"), ",");
	}

	/**
	 * @desc 获取简写Java类型
	 * @return 简写Java类型
	 */
	public String getSimpleJavaType() {
		if ("This".equals(getJavaType())) {
			return StringUtils.capitalize(genTable.getClassName());
		}
		return StringUtils.indexOf(getJavaType(), ".") != -1
				? StringUtils.substringAfterLast(getJavaType(), ".")
				: getJavaType();
	}

	/**
	 * @desc 获取简写Java字段
	 * @return 简写的Java字段
	 */
	public String getSimpleJavaField() {
		return StringUtils.substringBefore(getJavaField(), ".");
	}

	/**
	 * @desc 获取Java字段,如果是对象,则获取对象.附加属性1
	 * @return  Java字段属性
	 */
	public String getJavaFieldId() {
		return StringUtils.substringBefore(getJavaField(), "|");
	}

	/**
	 * @desc 获取Java字段,如果是对象,则获取对象.附加属性2
	 * @return Java字段属性
	 */
	public String getJavaFieldName() {
		String[][] ss = getJavaFieldAttrs();
		return ss.length > 0 ? getSimpleJavaField() + "." + ss[0][0] : "";
	}

	/**
	 * @desc 获取Java字段,所有属性名
	 * @return 属性信息
	 */
	public String[][] getJavaFieldAttrs() {
		String[] ss = StringUtils.split(StringUtils.substringAfter(getJavaField(), "|"), "|");
		String[][] sss = new String[ss.length][2];
		for (int i = 0; i < ss.length; i++) {
			sss[i][0] = ss[i];
			sss[i][1] = StringUtils.toUnderScoreCase(ss[i]);
		}
		return sss;
	}

	/**
	 * @desc 获取列注解列表
	 * @return 列注解列表
	 */
	public List<String> getAnnotationList() {
		List<String> list = Lists.newArrayList();
		// 导入Jackson注解
		if ("This".equals(getJavaType())) {
			list.add("com.fasterxml.jackson.annotation.JsonBackReference");
		}
		if ("java.util.Date".equals(getJavaType())) {
			list.add("com.fasterxml.jackson.annotation.JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\")");
		}

		// 导入JSR303验证依赖包
		if (!"1".equals(getIsNull()) && !"String".equals(getJavaType())) {
			list.add("javax.validation.constraints.NotNull(message=\"" + getComments() + "不能为空\")");
		} else if (!"1".equals(getIsNull()) && "String".equals(getJavaType()) && !"0".equals(getDataLength())) {
			list.add("org.hibernate.validator.constraints.Length(min=1, max=" + getDataLength()
					+ ", message=\"" + getComments() + "长度必须介于 1 和 " + getDataLength() + " 之间\")");
		} else if ("String".equals(getJavaType()) && !"0".equals(getDataLength())) {
			list.add("org.hibernate.validator.constraints.Length(min=0, max=" + getDataLength()
					+ ", message=\"" + getComments() + "长度必须介于 0 和 " + getDataLength() + " 之间\")");
		} else if ("BigDecimal".equals(getJavaType()) && !"0".equals(getDataLength())) {
			list.add("org.hibernate.validator.constraints.Digits(integer="+getNumLength()[0]+", fraction=" + getNumLength()[1]
					+ ", message=\"" + getComments() + "长度必须介于 0 和 " + getDataLength() + " 之间\")");
		}
		return list;
	}

	/**
	 * @desc 获取简写列注解列表
	 * @return 简写列注解列表
	 */
	public List<String> getSimpleAnnotationList() {
		List<String> list = Lists.newArrayList();
		for (String ann : getAnnotationList()) {
			list.add(StringUtils.substringAfterLast(ann, "."));
		}
		return list;
	}

	/**
	 * @desc 是否是基类字段
	 * @return 基类字段
	 */
	public Boolean getIsNotBaseField() {
		return !StringUtils.equals(getSimpleJavaField(), "id")
				&& !StringUtils.equals(getSimpleJavaField(), "remarks")
				&& !StringUtils.equals(getSimpleJavaField(), "createBy")
				&& !StringUtils.equals(getSimpleJavaField(), "createDate")
				&& !StringUtils.equals(getSimpleJavaField(), "updateBy")
				&& !StringUtils.equals(getSimpleJavaField(), "updateDate")
				&& !StringUtils.equals(getSimpleJavaField(), "delFlag");
	}
}